package com.wukang.photovoltaicinspectionpictures.logger

import android.util.Log
import java.io.File
import java.io.FileInputStream
import java.io.FileOutputStream
import java.util.zip.ZipEntry
import java.util.zip.ZipOutputStream

/**
 * 日志文件工具
 * @author wukang
 */
internal object RogFileUtils {
    private const val TAG = "RogFileUtils"

    /**
     * 创建文件夹
     */
    fun makeDir(file: File?) {
        file ?: return
        try {
            file.apply {
                if (!isDirectory) {
                    val ret = mkdirs()
                    Log.d(TAG, "mkdirs \"${file.path}\" ret: $ret")
                }
            }
        } catch (e: Exception) {
            Log.e(TAG, "mkdirs \"${file.path}\" error: ${e.message}")
        }
    }

    /**
     * 创建文件
     */
    fun makeFile(file: File?) {
        file ?: return
        try {
            file.apply {
                if (!isFile || !exists()) {
                    val ret = createNewFile()
                    Log.d(TAG, "createNewFile \"${file.path}\" ret: $ret")
                }
            }
        } catch (e: Exception) {
            Log.e(TAG, "createNewFile \"${file.path}\" error: ${e.message}")
        }
    }

    /**
     * 删除文件或文件夹
     */
    fun deleteFile(path: String?) {
        path ?: return
        deleteFile(File(path))
    }

    /**
     * 删除文件或文件夹
     */
    fun deleteFile(file: File?) {
        file ?: return
        try {
            deleteFileChild(file)
            val ret = file.delete()
            Log.d(TAG, "delete \"${file.path}\" ret: $ret")
        } catch (e: Exception) {
            Log.e(TAG, "delete \"${file.path}\" error ${e.message}")
        }
    }

    /**
     * 删除子文件或子文件夹
     */
    fun deleteFileChild(file: File?) {
        file ?: return
        try {
            if (!file.exists()) {
                return
            }
            if (file.isDirectory) {
                // 递归删除文件夹里的文件
                file.listFiles()?.forEach {
                    deleteFile(it)
                }
            }
        } catch (e: Exception) {
            Log.e(TAG, "delete \"${file.path}\" error ${e.message}")
        }
    }

    /**
     * 压缩文件和文件夹
     *
     * @param srcFile 要压缩的文件或文件夹
     * @param zipFile 压缩完成的Zip
     */
    fun ZipFolder(srcFile: File, zipFile: File) {
        try {
            //创建ZIP
            val outZip = ZipOutputStream(FileOutputStream(zipFile))
            //创建文件
            makeFile(srcFile)
            //压缩
            ZipFiles(srcFile, outZip)
            //完成和关闭
            outZip.finish()
            outZip.close()
        } catch (e: Exception) {
            Log.e(TAG, "zip \"${srcFile.path}\" error ${e.message}")
        }
    }

    /**
     * 压缩文件
     */
    @Throws(Exception::class)
    private fun ZipFiles(file: File, zipOutputSteam: ZipOutputStream) {
        if (file.isFile) {
            val zipEntry = ZipEntry(file.name)
            val inputStream = FileInputStream(file)
            zipOutputSteam.putNextEntry(zipEntry)
            var len: Int
            val buffer = ByteArray(4096)
            while ((inputStream.read(buffer).also { len = it }) != -1) {
                zipOutputSteam.write(buffer, 0, len)
            }
            zipOutputSteam.closeEntry()
        } else {
            //文件夹
            val fileList = file.listFiles()
            //没有子文件和压缩
            if (fileList.isNullOrEmpty()) {
                val zipEntry = ZipEntry(file.name + File.separator)
                zipOutputSteam.putNextEntry(zipEntry)
                zipOutputSteam.closeEntry()
                return
            }
            //子文件和递归
            for (child in fileList) {
                ZipFiles(child, zipOutputSteam)
            }
        }
    }

    /**
     * 清除历史文件
     */
    fun clearIfNeed(file: File?, maxSize: Long) {
        if (file == null) {
            return
        }

        try {
            val files = file.listFiles()
            if (files.isNullOrEmpty()) {
                return
            }
            // 倒序排序
            files.sortByDescending { it.lastModified() }

            var size: Long = 0
            files.forEach {
                size += it.length()
                if (size > maxSize) {
                    val ret = it.delete()
                    Log.d(TAG, "delete \"${it.path}\" ret: $ret")
                }
            }

        } catch (e: Exception) {
            Log.e(TAG, "clear \"${file.path}\" error ${e.message}")
        }
    }
}